package multithread.framework.threadpool;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import multithread.framework.threadmethod.ThreadResult;

public class MethodCompletionService implements CompletionService<ThreadResult> {
	private CompletionService<ThreadResult> completionService = null;
	private Executor exector = null;
	private long timeout;

	public MethodCompletionService(Executor exector, long timeout) {
		super();
		setExector(exector);
		setTimeout(timeout);
		completionService = new ExecutorCompletionService<ThreadResult>(exector);
	}

	@Override
	public Future<ThreadResult> submit(Callable<ThreadResult> task) {
		return completionService.submit(task);
	}

	@Override
	public Future<ThreadResult> submit(Runnable task, ThreadResult result) {
		return completionService.submit(task, result);
	}

	@Override
	public Future<ThreadResult> take() throws InterruptedException {
		if (timeout <= 0)
			return completionService.take();
		else {
//			 return poll(timeout, TimeUnit.SECONDS);
			//hand timeout
			Future<ThreadResult> future = poll();
			if (future == null) {
				Thread.sleep(timeout);
				return poll();
			}
			return future;
		}
	}

	@Override
	public Future<ThreadResult> poll() {
		return completionService.poll();
	}

	@Override
	public Future<ThreadResult> poll(long timeout, TimeUnit unit)
			throws InterruptedException {
		return completionService.poll(timeout, unit);
	}

	protected void setExector(Executor exector) {
		this.exector = exector;
	}

	protected Executor getExector() {
		return exector;
	}

	public long getTimeout() {
		return timeout;
	}

	public void setTimeout(long timeout) {
		this.timeout = timeout;
	}

}
